<template>
  <div style="width: 100%; height: 100%">
    <div id="cesiumContainer" style="width: 100%; height: 100%"></div>
    <div class="example" v-if="loading">
      <a-spin tip="Loading..." />
    </div>
  </div>
</template>

<script>
import { getAllDamInfo } from '@/api/record.js';
import ChinaJSON from './china3.json';
import ChinaVisit from './china.json';
// import CesiumNavigation from 'cesium-navigation-es6';
var viewer = null; // viewer对象不能绑定到vue的属性
export default {
  name: 'cesium',
  props: {
    checkedOne: {
      type: Boolean,
      default: true
    },
    checkedTwo: {
      type: Boolean,
      default: true
    },
    checkedThr: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      allProint: [],
      oneProint: [],
      twoProint: [],
      thrProint: [],
      loading: true
    };
  },
  mounted() {
    this.loading = true;
    this.getProint();
    Cesium.Ion.defaultAccessToken =
      'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjOTY5ZTdmNi1kYzUyLTRhMmItYTkwZC1lNjlkY2IzMTU0ZTMiLCJpZCI6MTYwOTU4LCJpYXQiOjE2OTIyNTgwODN9.fRAN7pdxLFuFR2FQoUawmL7VAVEiQ2mre2y6zPGWmpY';
    viewer = new Cesium.Viewer('cesiumContainer', {
      selectionIndicator: false,
      infoBox: false,
      animation: false,
      baseLayerPicker: false,
      timeline: false,
      geocoder: false,
      homeButton: false,
      enableCompass: false,
      enableCompassOuterRing: false,
      sceneModePicker: false,
      navigationHelpButton: false,
      orderIndependentTranslucency: false,
      fullscreenButton: false,
      contextOptions: {
        webgl: {
          alpha: false,
          preserveDrawingBuffer: false
        }
      },
      imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
        url: 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer'
      })
    });
    viewer._cesiumWidget._creditContainer.style.display = 'none';

    var camera = viewer.camera;
    camera.setView({
      destination: Cesium.Cartesian3.fromDegrees(105.3686, 33.3736, 10000000.0),
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-90),
        roll: Cesium.Math.toRadians(0)
      }
    });

    viewer.scene.morphTo2D(0);
    // // Cesium.flyHome
    // // 默认矩形框设置为亚洲
    // Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(90, -20, 110, 90);
    // // 将相机飞到主视图,即默认矩形框区域。
    // let duration = 2;
    // viewer.camera.flyHome(duration);

    // const tileset1 = viewer.scene.primitives.add(
    //   new Cesium.Cesium3DTileset({
    //     url: Cesium.IonResource.fromAssetId(1434626),
    //     // url: Cesium.IonResource.fromAssetId(1429445),
    //     //This tileset doesn't have a location, so we're using a modelMatrix to place it at 0, 0 instead of drawing at the center of the earth
    //     modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(
    //       Cesium.Cartesian3.fromDegrees(106.22445, 38.47997, 0)
    //       // Cesium.Cartesian3.fromDegrees(106.183, 38.489, 0)
    //     )
    //   })
    // );

    viewer.scene.logarithmicDepthBuffer = false;
    // 限制平移
    // viewer.scene.screenSpaceCameraController.enableTranslate = false;

    //限制镜头高度
    viewer.scene.screenSpaceCameraController.maximumZoomDistance = 10000000;
    viewer.scene.screenSpaceCameraController.minimumZoomDistance = 10;
    //实时监测镜头范围(该方法会一直调用)
    viewer.scene.preRender.addEventListener(() => {
      //计算镜头范围方法，该方法会计算当前镜头地理坐标（弧度）范围并返回west,east,north,south 4个范围参数
      const center = this.pickCenter();
      // console.log(rectangle,'rectangle');
      // //设置可浏览经纬度范围
      let Range = { lonleft: 70, lonRight: 145, lattop: 55, latbottom: 2 };

      //如果视角超出设置范围则跳转视角
      if (
        center.lon < Range.lonleft ||
        center.lon > Range.lonRight ||
        center.lat > Range.lattop ||
        center.lat < Range.latbottom
      ) {
        viewer.scene.camera.setView({
          destination: Cesium.Cartesian3.fromDegrees(105.3686, 33.3736, 10000000.0),
          orientation: {
            heading: Cesium.Math.toRadians(0),
            pitch: Cesium.Math.toRadians(-90),
            roll: Cesium.Math.toRadians(0)
          }
        });
      }
    });

    this.dd('', viewer);
    // 鼠标点击事件
    var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    handler.setInputAction(click => {
      const pick = viewer.scene.pick(click.position);
      let data = NaN;
      if (pick) {
        if (pick.id) {
          let targetItem = this.allProint.filter(item => item.id == pick.id._id)[0];

          this.flyTo(targetItem, 1500, true);
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    this.addProint();
    this.loadRiverGeoJson();

    var helper = new Cesium.EventHelper();
    helper.add(viewer.scene.globe.tileLoadProgressEvent, e => {
      if (e === 0) {
        this.loading = false;
      }
    });

    //具体事件的实现
    var canvas = viewer.scene.canvas;
    var ellipsoid = viewer.scene.globe.ellipsoid;
    var handler = new Cesium.ScreenSpaceEventHandler(canvas);
    handler.setInputAction(movement => {
      //捕获椭球体，将笛卡尔二维平面坐标转为椭球体的笛卡尔三维坐标，返回球体表面的点
      var cartesian = viewer.camera.pickEllipsoid(movement.endPosition, ellipsoid);
      if (cartesian) {
        //将笛卡尔三维坐标转为地图坐标（弧度）
        var cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian); //将地图坐标（弧度）转为十进制的度数
        var lat_String = Cesium.Math.toDegrees(cartographic.latitude).toFixed(4);
        var log_String = Cesium.Math.toDegrees(cartographic.longitude).toFixed(4);
        this.$emit('setCoordinate', log_String, lat_String);
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  },
  watch: {
    allProint() {
      this.addProint();
    },
    checkedOne(nl) {
      this.setnewProint();
    },
    checkedTwo(nl) {
      this.setnewProint();
    },
    checkedThr(nl) {
      this.setnewProint();
    }
  },
  methods: {
    getProint() {
      getAllDamInfo({}).then(res => {
        this.allProint = res.data.filter(item => item.longitude && item.longitude != '');
        this.oneProint = res.data.filter(item => item.longitude && item.longitude != '' && item.stationStatus == 1);
        this.twoProint = res.data.filter(item => item.longitude && item.longitude != '' && item.stationStatus == 2);
        this.thrProint = res.data.filter(item => item.longitude && item.longitude != '' && item.stationStatus == 3);
      });
    },
    setProint(x, y, z) {
      const position = Cesium.Cartesian3.fromDegrees(x, y, z);
      viewer.camera.setView({
        destination: position, // 相机位置
        orientation: {
          heading: Cesium.Math.toRadians(0), // 水平旋转  -正北方向
          pitch: Cesium.Math.toRadians(-90), // 上下旋转  --俯视朝向
          roll: 0 // 视口翻滚角度
          // // 指向
          // heading: 6.1107904016167005,
          // // 视角
          // pitch: -0.3156030705470225,
          // roll: 0.000005379510167990986
        }
      });
    },
    addProint() {
      viewer.entities.removeAll();
      this.allProint.map(item => {
        viewer.entities.add(
          new Cesium.Entity({
            id: item.id,
            code: item.id,
            name: item.stationName,
            position: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude),
            billboard: {
              image:
                item.stationStatus == 1 ? `printone.png` : item.stationStatus == 2 ? `printtwo.png` : `printthr.png`,
              width: 18,
              height: 20,
              pixelOffset: new Cesium.Cartesian2(0, -10)
            },
            label: {
              // text: item.stationName,
              font: '20px',
              outlineWidth: 3,
              fillColor: Cesium.Color.WHITE,
              backgroundColor: Cesium.Color.STEELBLUE,
              translucencyByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e5, 0.2),
              // backgroundColor: rgba(10, 61, 113, 1),
              showBackground: false, // 是否显示背景颜色
              style: Cesium.LabelStyle.FILL_AND_OUTLINE,
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
              pixelOffset: new Cesium.Cartesian2(0, -20)
            }
          })
        );
      });

      // viewer.entities.values.forEach(entity => {
      //   // if (entity !== chinaEntity) {
      //   console.log(entity);
      //   entity.show = false;
      //   // }
      // });
    },
    flyTo(item, height = 1500, falg = false) {
      this.removeVisit();
      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, height),
        orientation: {
          heading: Cesium.Math.toRadians(-10), // 水平旋转  -正北方向
          pitch: Cesium.Math.toRadians(-90), // 上下旋转  --俯视朝向
          roll: 19 // 视口翻滚角度
        },
        duration: 5.0
      });
      if (falg) {
        this.$emit('flyTo', item);
      }
    },
    // 描述地图
    async loadRiverGeoJson() {
      await viewer.dataSources.add(
        Cesium.GeoJsonDataSource.load('model/jsons/china.json', {
          stroke: Cesium.Color.fromCssColorString('#00DDFF'), // 线条颜色
          fill: Cesium.Color.PALETURQUOISE.withAlpha(0), // 注意：颜色必须大写，即不能为blue
          strokeWidth: 0
        })
      );
    },
    //
    // 单个省份高亮
    async loadRiverGeoJson2(name) {
      let selectVisit = ChinaVisit.features.filter(item => item.properties.name == name)[0];
      viewer.dataSources.remove(this.visitzoing);
      this.visitzoing = await viewer.dataSources.add(
        Cesium.GeoJsonDataSource.load(selectVisit, {
          stroke: Cesium.Color.AQUA,
          fill: Cesium.Color.fromCssColorString('rgba(0, 221, 255, 0.3)'), // 注意：颜色必须大写，即不能为blue
          strokeWidth: 0
        })
      );
    },
    // 移除高亮省份
    removeVisit() {
      viewer.dataSources.remove(this.visitzoing);
    },

    setnewProint() {
      let arr = [];
      if (this.checkedOne) {
        arr = arr.concat(this.oneProint);
      }
      if (this.checkedTwo) {
        arr = arr.concat(this.twoProint);
      }
      if (this.checkedThr) {
        arr = arr.concat(this.thrProint);
      }
      this.allProint = arr;
    },
    pickCenter() {
      let ellipsoid = viewer.camera.pickEllipsoid(
        new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas.clientHeight / 2)
      );
      let curPosition = viewer.scene.globe.ellipsoid.cartesianToCartographic(ellipsoid);
      let lon = (curPosition.longitude * 180) / Math.PI;
      let lat = (curPosition.latitude * 180) / Math.PI;
      return {
        lon: lon,
        lat: lat
      };
    },
    zoomByBound(flag) {
      const center = this.pickCenter();
      let height = viewer.camera.positionCartographic.height;
      const camera = viewer.camera;
      let boundingSph = new Cesium.BoundingSphere(Cesium.Cartesian3.fromDegrees(center.lon, center.lat, 0), height);
      let moveRate = 0;
      if (flag) {
        moveRate = 0.5;
      } else {
        moveRate = 1.5;
      }
      let zoomParams = {
        duration: 0.8,
        offset: new Cesium.HeadingPitchRange(camera.heading, camera.pitch, height * moveRate)
      };
      camera.flyToBoundingSphere(boundingSph, zoomParams);
    },
    // 拉近视距
    amplifyMap() {
      // // 获取当前镜头位置的笛卡尔坐标
      // let cameraPos = viewer.camera.position;
      //
      // // 获取当前坐标系标准
      // let ellipsoid = viewer.scene.globe.ellipsoid;
      //
      // // 根据坐标系标准，将笛卡尔坐标转换为地理坐标
      // let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
      //
      // // 获取镜头的高度
      // let height = cartographic.height;
      //
      // let centerLon = parseFloat(Cesium.Math.toDegrees(cartographic.longitude).toFixed(8));
      // let centerLat = parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(8));
      //
      // // 镜头拉近
      // viewer.camera.flyTo({
      //   destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, height / 1.8),
      //   duration: 1.0
      // });
      // let position = viewer.camera.positionCartographic;
      // viewer.camera.moveForward(position.height * 0.2)
      this.zoomByBound(1);
    },
    // 缩小视距
    reduceMap() {
      // // 获取当前镜头位置的笛卡尔坐标
      // let cameraPos = viewer.camera.position;
      //
      // // 获取当前坐标系标准
      // let ellipsoid = viewer.scene.globe.ellipsoid;
      //
      // // 根据坐标系标准，将笛卡尔坐标转换为地理坐标
      // let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
      //
      // // 获取镜头的高度
      // let height = cartographic.height;
      //
      // let centerLon = parseFloat(Cesium.Math.toDegrees(cartographic.longitude).toFixed(8));
      // let centerLat = parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(8));
      // // 镜头拉远
      // viewer.camera.flyTo({
      //   destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, height * 1.8),
      //   duration: 1.0
      // });
      this.zoomByBound(0);
    },
    // 2D 3D切换
    change() {
      if (viewer.scene.mode === Cesium.SceneMode.SCENE2D) {
        // 3D
        viewer.scene.morphTo3D(0);
        this.$emit('setScene', '2D');
      } else if (viewer.scene.mode === Cesium.SceneMode.SCENE3D) {
        // 2D
        viewer.scene.morphTo2D(0);
        this.$emit('setScene', '3D');
      }
    },
    // 添加遮罩层
    dd(geojson, viewer) {
      geojson = ChinaJSON;
      let arr = [];
      geojson.features[0].geometry.coordinates[0].forEach(item => {
        arr.push(item[0]);
        arr.push(item[1]);
      });
      // geojson.features[0].geometry.coordinates[0][0].forEach(item => {
      //   arr.push(item[0]);
      //   arr.push(item[1]);
      // });
      var polygonWithHole = new Cesium.PolygonGeometry({
        polygonHierarchy: new Cesium.PolygonHierarchy(
          Cesium.Cartesian3.fromDegreesArray([73.0, 80.0, 73.0, 0.0, 136.0, 0.0, 136.0, 80.0]),
          [new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(arr))]
        )
      });
      var geometry = Cesium.PolygonGeometry.createGeometry(polygonWithHole);
      let instances = [];
      instances.push(
        new Cesium.GeometryInstance({
          geometry: geometry,
          attributes: {
            color: Cesium.ColorGeometryInstanceAttribute.fromColor(
              Cesium.Color.fromCssColorString('rgba(0, 0, 0, 0.5)')
            )
          }
        })
      );
      function addRect(instances, left, down, right, up) {
        instances.push(
          new Cesium.GeometryInstance({
            geometry: new Cesium.RectangleGeometry({
              rectangle: Cesium.Rectangle.fromDegrees(left, down, right, up)
            }),
            attributes: {
              color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                Cesium.Color.fromCssColorString('rgba(0, 0, 0, 0.5)')
              )
            }
          })
        );
      }
      addRect(instances, 73.0, 80.0, 136.0, 90.0);
      addRect(instances, -180.0, -90.0, 73.0, 90.0);
      addRect(instances, 136.0, -90.0, 180.0, 90.0);
      addRect(instances, 73.0, -90.0, 136.0, 0.0);

      viewer.scene.primitives.add(
        new Cesium.Primitive({
          geometryInstances: instances,
          appearance: new Cesium.PerInstanceColorAppearance({
            // flat: true
            // translucent: false
          })
        })
      );
    }
  }
};
</script>
<style scoped>
.example {
  width: 100%;
  height: 100%;
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  left: 0;
  top: 0;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 4px;
}
</style>
